package models

import (
	"fmt"

	"time"

	"github.com/beego/beego/v2/server/web"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
)

var DB *gorm.DB
var err error

func init() {
	mysqluser, _ := web.AppConfig.String("mysqluser")
	mysqlpass, _ := web.AppConfig.String("mysqlpass")
	mysqlurls, _ := web.AppConfig.String("mysqlurls")
	mysqldb, _ := web.AppConfig.String("mysqldb")
	httpport, _ := web.AppConfig.String("mysqlhttpport")
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_unicode_ci&parseTime=True&loc=Local",
		mysqluser, mysqlpass, mysqlurls, httpport, mysqldb)
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		SkipDefaultTransaction:                   true,                                //禁用默认事务
		Logger:                                   logger.Default.LogMode(logger.Info), //日志配置
		DisableForeignKeyConstraintWhenMigrating: true,                                //禁用外键约束
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true,
		}, //表名单数
	})

	// 配置连接池
	if err == nil {
		sqlDB, err := DB.DB()
		if err == nil {
			// 设置最大打开连接数
			sqlDB.SetMaxOpenConns(100)
			// 设置最大空闲连接数
			sqlDB.SetMaxIdleConns(10)
			// 设置连接最大生存时间
			sqlDB.SetConnMaxLifetime(time.Hour)
			// 设置连接最大空闲时间
			sqlDB.SetConnMaxIdleTime(time.Minute * 30)
		}
	}
	if err != nil {
		fmt.Println("连接mysql数据库失败", err)
	} else {
		fmt.Println("连接mysql数据库成功")
	}
	DB.Callback().Create().Before("gorm:create").Register("set_create_time", setCreateTimeCallback)
	// 全局回调函数，在更新记录之前设置更新时间
	DB.Callback().Update().Before("gorm:update").Register("set_update_time", setUpdateTimeCallback)
}

// GetUnix 获取当前时间戳
func GetUnix() int64 {
	return time.Now().Unix()
}

// 全局回调函数，在创建记录之前设置新增时间
func setCreateTimeCallback(db *gorm.DB) {
	if _, ok := db.Statement.Schema.FieldsByName["CreatedAt"]; ok {
		now := int(GetUnix())
		db.Statement.SetColumn("CreatedAt", now)
	}
}

// 全局回调函数，在更新记录之前设置更新时间
func setUpdateTimeCallback(db *gorm.DB) {
	if _, ok := db.Statement.Schema.FieldsByName["UpdateTime"]; ok {
		now := int(GetUnix())
		db.Statement.SetColumn("UpdateTime", now)
	}
}
